import {
  debounce
} from "./index"
import {
  wsUrl
} from "../api/request"

class Scoket {
  exit = false
  wsbaseUrl = ""
  wsConnect = null
  connectLoading = false
  event = {
    getWsReadyState: function () {}
  }

  // 重连次数
  reconnectNumber = {
    max: 100,
    current: 0
  }
  // 重连
  //链接次数小的话就进行重新链接
  reconnect = debounce(function () {
    if (this.exit) return
    if (this.reconnectNumber.current < this.reconnectNumber.max) {
      this.reconnectNumber.current++
      this.init()
    }
  }, 3000, false)
  // 联系人列表
  contactList = []
  // 每4秒同步一次联系人列表
  saveContactList = debounce(function () {
    wx.setStorage({
      key: "contactList",
      data: this.contactList.slice(0, 100)
    })
  }, 4000, false)
  // 进入的房间
  room = {
    code: "",
    fn() {}
  }
  badge = 0

  constructor() {
    this.isConnect()
  }

  isConnect() {
    if (this.wsConnect) return
    this.exit = false
    const userInfo = wx.getStorageSync('userInfo'),
      token = wx.getStorageSync('token')
    if (!token || !userInfo || !userInfo.code) return
    this.wsbaseUrl = wsUrl + userInfo.code + "/?token=" + token

    wx.getStorage({
      key: 'contactList'
    }).then(res => {
      const data = res?.data || []
      this.contactList = data
      this.badge = data.reduce((sum, item) => {
        sum += (item.count ?? 0)
        return sum
      }, 0)
      this.setBadge()
    }).catch(_ => {
      this.contactList = []
    })

    this.init()
  }

  init() {
    if (this.connectLoading) return
    this.connectLoading = true
    this.wsConnect = wx.connectSocket({
      url: this.wsbaseUrl,
      perMessageDeflate: true,
      timeout: 5000,
      // header:{
      //   'Cookie': 'sessionid=yhucrbxhesnsf6c0329a4va60cu2038t '
      // },
      success: (res) => {
        setTimeout(_ => {
          this.wsConnect.onOpen(this.onOpen.bind(this))
          this.wsConnect.onMessage(this.onMessage.bind(this))
          this.wsConnect.onError(this.onError.bind(this))
          this.wsConnect.onClose(this.onClose.bind(this))
        }, 10)
      },
      fail: (res) => {
        console.log("fail", res)
      },
      complete: (res) => {
        this.connectLoading = false
      },
    })

  }

  send(data, callBack) {
    this.wsConnect.send({
      data: JSON.stringify(data),
      success: () => {
        if (typeof callBack === 'function') callBack(data)
      },
      fail: () => {
        wx.showToast({
          title: '发送失败',
          icon: "error"
        })
        this.reconnect()
      }
    })
  }

  onRoom(code, fn) {
    this.room = {
      code,
      fn
    }
    const index = this.contactList.findIndex(item => item.job_number == code)
    if (index > -1) {
      const count = this.contactList[index].count
      this.contactList[index].count = 0
      this.badge = this.badge - count
      this.setBadge()
      this.saveContactList()
    }
  }


  setBadge() {
    if (this.badge) {
      const badge = this.badge > 99 ? "99+" : this.badge + ''
      wx.setTabBarBadge({
        index: 1,
        text: badge
      })
    } else {
      wx.removeTabBarBadge({
        index: 1,
      })
    }
  }

  removeRoom() {
    this.room = {}
  }


  on(name, callBack) {
    if (typeof callBack !== 'function') 
    throw new Error("必须绑定函数")
    this.event[name] = callBack
    return this
  }

  remove(name) {
    delete this.event[name]
  }

  emit(name, data) {
    if (name) {
      this.event[name] && this.event[name](data)
    } else {
      for (const key in this.event) {
        this.event[key](data)
      }
    }

  }

  onOpen(res) {
    this.reconnectNumber.current = 0
    this.emit("getWsReadyState")
  }

  onMessage(res) {
    try {
      const data = JSON.parse(res.data)
      if (!data.from || !data.form_name || !data.form_people_img) return
      const flag = this.room.code == data.from
      const options = {
        name: data.form_name,
        picture: data.form_people_img,
        job_number: data.from,
        message: data.message.slice(0, 50)
      }
      this.changeContactList(options, flag)

      if (flag) {
        this.room.fn(data)
      }
    } catch (error) {

    }

  }

  changeContactList(ops, flag) {
    const index = this.contactList.findIndex(item => item.job_number == ops.job_number)
    if (index > -1) {
      const count = flag ? 0 : this.contactList[index].count + 1
      ops.count = count
      this.contactList.splice(index, 1)
      this.contactList.unshift(ops)
    } else {
      ops.count = flag ? 0 : 1
      this.contactList.unshift(ops)
    }
    if (!flag) {
      ++this.badge
      this.setBadge()
    }
    this.emit(null, this.contactList)
    this.saveContactList()
  }

  deleteContact(code) {
    const index = this.contactList.findIndex(item => item.job_number == code)
    if (index > -1) {
      const count = this.contactList[index].count
      this.contactList.splice(index, 1)
      if (count > 0) {
        this.badge = this.badge - count
        this.setBadge()
      }
      this.saveContactList()
    }
    return this.contactList
  }

  onError(res) {
    console.log("onError", res)
    this.emit("getWsReadyState")
    this.reconnect()
  }

  onClose(res) {
    console.log("onClose", res)
    if (res.code !== 1000) {
      this.reconnect()
    }
    this.emit("getWsReadyState")
  }

  close() {
    this.exit = true
    if (this.wsConnect) {
      this.wsConnect.close()
      this.wsConnect = null
    }

  }



}


export default Scoket